/*
d) makedir (parent_path, dir_name) – To create a new directory whose name should be
<dir_name> in path specified by <parent_path> where '/' is considered as 'root'
directory.
e) deletedir (name) – To remove a file or a directory as indicated by < name>
f) movedir (source_dir_name,dest_dir_name) – To move a sub-tree
<source_dir_name> to <dest_dir_name> directory.
g) listdir (dir_name,flag) – List all the contents according to <flag> of the current directory
i.e. specified by <dir_name>.
*/
#include <stdio.h>
#include <string.h>
#include "../include/DirectoryOperations.h"
#include "../include/NAry.h"
#include "../include/BST.h"

//extern int isVFSMounted;
int make_dir(char *parentPath, char *dirName)
{
	
	//if(fileSysInfo.isUnmounted==1)
	//	return 5;
	if(isVFSMounted==0)
		return 5;

	if((strcmp(parentPath, "")==0) || (strcmp(dirName, "")==0))
		return 0;
		

	//FileDescriptor -- Add to N Ary Tree --	
	int i;
	if(fileSysInfo.maxFileDescriptors == fileSysInfo.usedFileDescriptors)
		return 1;

	for(i=0; dirName[i]!='\0'; i++)
		if(dirName[i]=='/')
			return 2;
	
	char fullFileName[100];
	strcpy(fullFileName, parentPath);
	if(parentPath[strlen(parentPath)-1]!='/')
		strcat(fullFileName, "/");
	strcat(fullFileName, dirName);

	//printf("%s", fullFileName);

	BSTNode *bstNode = search_bst_node(fullFileName);	
	if(bstNode!=NULL)
		return 3;

	char *p, *q, r[100];
	char dirname1[100];
	strcpy(dirname1, fullFileName);
	q = strtok(dirname1, "/");
	//printf("Full Name: %s", fullFileName);
	strcpy(r, "");
	while(q!=NULL) 
	{
		strcat(r, "/");
		strcat(r, q);
		BSTNode *bstNode = search_bst_node(r);	
		if(bstNode==NULL)
		{
			fileDescriptor fd;
			fd.block = -1;
			strcpy(fd.locationFullPath, r);
			strcpy(fd.fileName, q);
			strcpy(fd.fileType, "dir");
			//printf("%s\n", fd.locationFullPath);
			
			NAryNode *directory = insertNAryNode(&fd);
			insert_bst_node(&BSTRoot, directory->fd.locationFullPath, directory);	
			insert_hash_item(directory->fd.fileName, directory);
			

		}
		q = strtok(NULL, "/");
	}
	construct_bst_tree();
	construct_hash_table();
	return -1;
}

int list_dir(char *dirpath, int flag, char *fileName)
{
	//if(fileSysInfo.isUnmounted==1)
//		return 4;
	if(dirpath[strlen(dirpath)-1]=='/' && strcmp(dirpath, "/")!=0)
		dirpath[strlen(dirpath)-1]='\0';
	if(isVFSMounted==0)
		return 3;

	if((strcmp(dirpath, "")==0) || (strcmp(fileName, "")==0))
		return 0;
	BSTNode *bstNode = search_bst_node(dirpath);
	if(bstNode==NULL)
		return 1;
	if(flag!=0 && flag!=1)
		return 2;
	FILE *fp = fopen(fileName, "w+");
	if(fp==NULL)
		return 4;
	fclose(fp);
	fp = fopen(fileName, "w");
	displayNAryNode(dirpath, flag, fp);
	fclose(fp);
	return -1;
}

int move_dir (char *source_dir_name, char *dest_dir_name)
{
	if( source_dir_name[strlen(source_dir_name)-1]=='/' && strcmp(source_dir_name, "/")!=0 )
		source_dir_name[strlen(source_dir_name)-1]='\0';
	//if(fileSysInfo.isUnmounted==1)
	//	return 8;
	if(isVFSMounted==0)
		return 8;
	if((strcmp(source_dir_name, "")==0) || (strcmp(dest_dir_name, "")==0))
		return 0;		
	
	BSTNode *bstNode = search_bst_node(source_dir_name);	
	if(bstNode==NULL)
		return 1;
	bstNode = search_bst_node(dest_dir_name);
	if(bstNode==NULL)
	{
		return 2;
	}

	bstNode = search_bst_node(source_dir_name);
	NAryNode *nAryNode1 = bstNode->nAryNode;
	if(strcmp(nAryNode1->fd.fileType, "fil")==0)
		return 4;
	bstNode = search_bst_node(dest_dir_name);
	nAryNode1 = bstNode->nAryNode;
	if(strcmp(nAryNode1->fd.fileType, "fil")==0)
		return 7;
	bstNode = search_bst_node(source_dir_name);
	char destfile[100] ;
	strcpy(destfile, dest_dir_name);
	if(destfile[strlen(destfile)-1]!='/')		
		strcat(destfile, "/");
	strcat(destfile, bstNode->nAryNode->fd.fileName);
	bstNode = search_bst_node(destfile);
	if(bstNode!=NULL)
		return 5;
	if( strlen(source_dir_name)<=strlen(dest_dir_name) )
	  if( strncmp(dest_dir_name, source_dir_name, strlen(source_dir_name))==0 )
		return 6;
	moveNAryNode(source_dir_name, dest_dir_name, "dir");

	construct_bst_tree();
	construct_hash_table();
	return -1;
}

int delete_dir(char *dirName,int flag) 
{
	//if(fileSysInfo.isUnmounted==1)
	//	return 4;
	if(strcmp(dirName, "/")==0)
		return -1;
	if( dirName[strlen(dirName)-1]=='/' && strcmp(dirName, "/")!=0 )
		dirName[strlen(dirName)-1]='\0';

	if(isVFSMounted==0)
		return 4;
	if(strcmp(dirName, "")==0 )
		return 0;
	BSTNode *bstNode = search_bst_node(dirName);
	if(bstNode==NULL)
		return 1;

	NAryNode *nAryNode = bstNode->nAryNode;
	if( flag==0 && (nAryNode->files!=NULL || nAryNode->directories!=NULL) )
	{
		return 2;
	}
	/*int i;
	for(i=0; dirName[i]!='\0'; i++)
		if( !(isalpha(dirName[i]) || isdigit(dirName[i]) || (dirName[i]=='/' && dirName[i+1]!='/')) )
			return 3;*/
	int blockno = deleteNAryNode(dirName, "dir");
	fileSysInfo.usedFileDescriptors--;
	construct_bst_tree();
	construct_hash_table();
	return -1;
}

int copydir(char *sourceDirectory, char *destinationDirectory)
{
	copyNAryNode(sourceDirectory, destinationDirectory, "dir");
	construct_bst_tree();
	construct_hash_table();
	return 0;
}
